.pnt2sp <- function(obj){
  if (is.null(obj)) {
    warning("object obj is null.")
    return(NULL)
  }
  if (is.vector(obj) || is.list(obj)) {
    pnts <- matrix(nrow=length(obj), ncol=2)
    i <- 1
    for(geo in obj){
      if(tolower(GetType(geo)) == "point"){
        pnt <- GetPoints(geo)
        pnts[i, ] <- pnt
        i <- i+1
      } else {
        warning("not a geopoint.")
      }
    }
    return(sp::SpatialPoints(pnts))
  } else {
    if (tolower(GetType(obj)) == "point") {
      pnts <- GetPoints(obj)
      return(sp::SpatialPoints(pnts))
    } else {
      warning("obj is not point geometry")
      return(NULL)
    }
  }
}

.line2sp <- function(obj){
  line.pnts <- GetPoints(obj)
  if (!is.null(line.pnts)) {
    pnts <- line.pnts[[1]]
    polys <- line.pnts[[2]]
    lines <- vector(mode="list", length=length(polys))
    index <- 1
    i <- 1
    for(sub in polys){
      subpnts <- pnts[(index:(index+sub-1)), ]
      spLine <- sp::Line(coords = subpnts)
      lines[i] <- list(spLine)
      i <- i + 1
      index <- index + sub
    }
    spLines <- sp::Lines(lines, ID=GetID(obj))
    return(spLines)
  } else {
    warning("getting geometry spatial points failure")
    return(NULL)
  }
}

.region2sp <- function(obj) {
  regions <- list(obj)
  if( GetSubCount(obj) > 1 ){
    decompose.regions <- ProtectedDecompose(obj)
    regions <- decompose.regions
  }
  polygons <- vector(mode="list", length=length(regions))
  index.region <- 1
  for(region in regions){
    region.pnts <- GetPoints(region)
    if (!is.null(region.pnts)) {
      pnts <- region.pnts[[1]]
      polys <- region.pnts[[2]]
      sub.polygons <- vector(mode="list", length = length(polys))
      index <- 1
      i <- 1
      holes <- CheckPolygon(region)
      for(sub in polys){
        subpnts <- pnts[(index:(index+sub-1)), ]
        spPolygon <- sp::Polygon(coords=subpnts, hole=holes[i])
        sub.polygons[i] <- list(spPolygon)
        i <- i + 1
        index <- index + sub
      }
    } else {
      warning("getting geometry spatial points failure ")
    }
    polygons[index.region] <- sub.polygons
    index.region <- index.region + 1
  }
  spPolygons <- sp::Polygons(polygons, ID=GetID(obj))
  return(spPolygons)
}

.Geometrys2Sp <- function(obj){
  if (is.null(obj)) {
    stop("obj is null.")
  }
  if (!is.vector(obj) && !is.list(obj)) {
    return(Geometry2Sp(obj))
  }
  count <- length(obj)
  if(count == 0){
    stop("count must be greater 0")
  }
  geoType <- tolower(GetType(obj[[1]]))
  if (geoType == "point") {
    return(.pnt2sp(obj))
  } else if(geoType == "line") {
    spgeos <- lapply(obj, FUN = ".run" <- function(geo){
      return(.line2sp(geo))
    })
    #spgeos <- vector(mode = "list", count)
    #i <- 1
    #for(geo in obj){
    #  spgeo <- .line2sp(geo)
    #  if(!is.null(spgeo)){
    #    spgeos[i] <- spgeo
    #    i <- i+1
    #  }
    #}
    return(sp::SpatialLines(spgeos))
  } else if (geoType == "region") {
    #spgeos <- vector(mode = "list", count)
    #i <- 1
    #for(geo in obj){
    #  spgeo <- .region2sp(geo)
    #  if(!is.null(spgeo)){
    #    spgeos[i] <- spgeo
    #    i <- i+1
    #  }
    #}
      spgeos <- lapply(obj, FUN = ".run" <- function(geo){
      return(.region2sp(geo))
    })
    return(sp::SpatialPolygons(spgeos))
  } else {
    stop("Unsupported SuperMap geometry type.")
  }
}

Geometry2Sp <- function(obj){
  if (is.null(obj)) {
    stop(" obj is null.")
  }
  if (is.list(obj) || is.vector(obj)) {
    return(.Geometrys2Sp(obj))
  }
  if (!.IsGeoTypeValid(GetType(obj))) {
    stop("Unsupported SuperMap geometry type.")
  }
  
  geoType <- tolower(GetType(obj))
  if (geoType == "point") {
    return(.pnt2sp(obj))
  } else if(geoType == "line") {
    return(sp::SpatialLines(list(.line2sp(obj))))
  } else if(geoType == "region") {
    return(sp::SpatialPolygons(list(.region2sp(obj))))
  } else {
    stop("Unsupported SuperMap geometry type.")
  }
}